package com.example.zbh.dsliao.ui.activty;

import android.content.Context;
import android.media.AudioManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.media.SoundPool;
import android.net.Uri;
import android.os.Handler;
import android.os.SystemClock;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.easemob.chat.EMCallStateChangeListener;
import com.easemob.chat.EMChatManager;
import com.easemob.chat.EMMessage;
import com.easemob.chat.EMVideoCallHelper;
import com.easemob.chat.TextMessageBody;
import com.easemob.exceptions.EMServiceNotReadyException;
import com.example.zbh.dsliao.R;
import com.example.zbh.dsliao.constant.Constant;
import com.example.zbh.dsliao.utils.CameraHelper;

import java.util.UUID;

/**
 * Created by zbh on 15/11/29.
 */
public class VideoCallActivity extends BaseActivity implements View.OnClickListener {
    private boolean isInComingCall;
    private String userName;
    private CallingState callingState = CallingState.CANCED;
    private String callDruationText;
    private String msgId;
    private AudioManager audioManager;
    private SoundPool soundPool;
    private Ringtone ringtone;
    private int outgoing;
    private int streamID;
    private boolean endCallTriggerByMe = false;
    private EMCallStateChangeListener callStateListener;

    private SurfaceView localSurfaceView;
    private SurfaceHolder localSurfaceHolder;
    private static SurfaceView oppositeSurface;
    private SurfaceHolder oppositeSurfaceHolder;
    private boolean isMuteState;
    private boolean isHandsfreeState;
    private boolean isAnswered;
    private boolean monitor = true;
    private EMVideoCallHelper callHelper;
    private TextView callStateTextView, nickTextView, monitorTextView;
    private Handler handler = new Handler();
    private LinearLayout comingBtnContainer, voiceContronlLayout, topContainer, bottomContainer;
    private Button refuseBtn, answerBtn, hangupBtn;
    private ImageView muteImage, handsFreeImage;
    private Chronometer chronometer;
    private RelativeLayout rootContainer, btnsContainer;
    private CameraHelper cameraHelper;

    @Override
    protected int getLayOut() {
        return R.layout.activity_video_call;
    }

    @Override
    protected void initView() {
        callStateTextView = findeView(R.id.tv_call_state);
        comingBtnContainer = findeView(R.id.ll_coming_call);
        rootContainer = findeView(R.id.root_layout);
        refuseBtn = findeView(R.id.btn_refuse_call);
        answerBtn = findeView(R.id.btn_answer_call);
        hangupBtn = findeView(R.id.btn_hangup_call);
        muteImage = findeView(R.id.iv_mute);
        handsFreeImage = findeView(R.id.iv_handsfree);
        callStateTextView = findeView(R.id.tv_call_state);
        nickTextView = findeView(R.id.tv_nick);
        chronometer = findeView(R.id.chronometer);
        voiceContronlLayout = findeView(R.id.ll_voice_control);
        btnsContainer = findeView(R.id.ll_btns);
        topContainer = findeView(R.id.ll_top_container);
        bottomContainer = findeView(R.id.ll_bottom_container);
        monitorTextView = findeView(R.id.tv_call_monitor);

    }

    @Override
    protected void initData() {
        audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        refuseBtn.setOnClickListener(this);
        answerBtn.setOnClickListener(this);
        hangupBtn.setOnClickListener(this);
        muteImage.setOnClickListener(this);
        handsFreeImage.setOnClickListener(this);
        rootContainer.setOnClickListener(this);

        msgId = UUID.randomUUID().toString();
        // 获取通话是否为接收方向的
        isInComingCall = getIntent().getBooleanExtra("isComingCall", false);
        userName = getIntent().getStringExtra("username");
        // 设置通话人
        nickTextView.setText(userName);
        // 显示本地图像的surfaceview
        localSurfaceView = (SurfaceView) findViewById(R.id.local_surface);
        localSurfaceView.setZOrderMediaOverlay(true);
        localSurfaceView.setZOrderOnTop(true);
        localSurfaceHolder = localSurfaceView.getHolder();

        // 获取callHelper,cameraHelper
        callHelper = EMVideoCallHelper.getInstance();
        cameraHelper = new CameraHelper(callHelper, localSurfaceHolder);

// 显示对方图像的surfaceview
        oppositeSurface = (SurfaceView) findViewById(R.id.opposite_surface);
        oppositeSurfaceHolder = oppositeSurface.getHolder();
        // 设置显示对方图像的surfaceview
        callHelper.setSurfaceView(oppositeSurface);

        localSurfaceHolder.addCallback(new LocalCallback());
        oppositeSurfaceHolder.addCallback(new OppositeCallback());

        // 设置通话监听
        addCallStateListener();
        if (!isInComingCall) {// 拨打电话
            soundPool = new SoundPool(1, AudioManager.STREAM_RING, 0);
            outgoing = soundPool.load(this, R.raw.em_outgoing, 1);

            comingBtnContainer.setVisibility(View.INVISIBLE);
            hangupBtn.setVisibility(View.VISIBLE);

            callStateTextView.setText("正在连接对方");

            handler.postDelayed(new Runnable() {
                public void run() {
                    streamID = playMakeCallSounds();
                }
            }, 300);
        } else { // 有电话进来
            voiceContronlLayout.setVisibility(View.INVISIBLE);
            localSurfaceView.setVisibility(View.INVISIBLE);
            Uri ringUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
            audioManager.setMode(AudioManager.MODE_RINGTONE);
            audioManager.setSpeakerphoneOn(true);
            ringtone = RingtoneManager.getRingtone(this, ringUri);
            ringtone.play();
        }


    }

    /**
     * 设置通话状态监听
     */
    public void addCallStateListener() {
        callStateListener = new EMCallStateChangeListener() {

            @Override
            public void onCallStateChanged(CallState callState, CallError error) {
                // Message msg = handler.obtainMessage();
                switch (callState) {

                    case CONNECTING: // 正在连接对方
                        runOnUiThread(new Runnable() {

                            @Override
                            public void run() {
                                callStateTextView.setText("正在连接对方");
                            }

                        });
                        break;
                    case CONNECTED: // 双方已经建立连接
                        runOnUiThread(new Runnable() {

                            @Override
                            public void run() {
                                callStateTextView.setText("已经和对方建立连接,正在等待对方的接收...");
                            }

                        });
                        break;

                    case ACCEPTED: // 电话接通成功
                        runOnUiThread(new Runnable() {

                            @Override
                            public void run() {
                                try {
                                    if (soundPool != null)
                                        soundPool.stop(streamID);
                                } catch (Exception e) {
                                }
                                openSpeakerOn();
                                ((TextView) findViewById(R.id.tv_is_p2p)).setText(EMChatManager.getInstance().isDirectCall()
                                        ? "direct" : "replay");
                                handsFreeImage.setImageResource(R.mipmap.dl_icon_speaker_on);
                                isHandsfreeState = true;
                                chronometer.setVisibility(View.VISIBLE);
                                chronometer.setBase(SystemClock.elapsedRealtime());
                                // 开始记时
                                chronometer.start();
                                nickTextView.setVisibility(View.INVISIBLE);
                                callStateTextView.setText("通话中");
                                callingState = CallingState.NORMAL;

                            }

                        });
                        break;
                    case DISCONNNECTED: // 电话断了
                        final CallError fError = error;
                        runOnUiThread(new Runnable() {
                            private void postDelayedCloseMsg() {
                                handler.postDelayed(new Runnable() {

                                    @Override
                                    public void run() {
                                        saveCallRecord();
                                        Animation animation = new AlphaAnimation(1.0f, 0.0f);
                                        animation.setDuration(800);
                                        rootContainer.startAnimation(animation);
                                        finish();
                                    }

                                }, 200);
                            }

                            @Override
                            public void run() {
                                chronometer.stop();
                                callDruationText = chronometer.getText().toString();


                                if (fError == CallError.REJECTED) {
                                    callingState = CallingState.BEREFUESD;
                                    callStateTextView.setText("对方拒绝进行接收");
                                } else if (fError == CallError.ERROR_TRANSPORT) {
                                    callStateTextView.setText("连接建立失败");
                                } else if (fError == CallError.ERROR_INAVAILABLE) {
                                    callingState = CallingState.OFFLINE;
                                    callStateTextView.setText("对方不在线,请稍后再拨");
                                } else if (fError == CallError.ERROR_BUSY) {
                                    callingState = CallingState.BUSY;
                                    callStateTextView.setText("对方这在通话中,请稍后再拨");
                                } else if (fError == CallError.ERROR_NORESPONSE) {
                                    callingState = CallingState.NORESPONSE;
                                    callStateTextView.setText("对方未接听");
                                } else {
                                    if (isAnswered) {
                                        callingState = CallingState.NORMAL;
                                        if (endCallTriggerByMe) {
                                            callStateTextView.setText("挂断");
                                        } else {
                                            callStateTextView.setText("对方已经挂断");
                                        }
                                    } else {
                                        if (isInComingCall) {
                                            callingState = CallingState.UNANSWERED;
                                            callStateTextView.setText("未接听");
                                        } else {
                                            if (callingState != CallingState.NORMAL) {
                                                callingState = CallingState.CANCED;
                                                callStateTextView.setText("已取消");
                                            } else {
                                                callStateTextView.setText("挂断");
                                            }
                                        }
                                    }
                                }
                                postDelayedCloseMsg();
                            }

                        });

                        break;

                    default:
                        break;
                }

            }
        };
        EMChatManager.getInstance().addCallStateChangeListener(callStateListener);
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_refuse_call://拒绝接听
                clickRefuse();
                break;
            case R.id.btn_answer_call: // 接听电话
                clickAnswer();
                break;
            case R.id.btn_hangup_call: // 挂断电话
                clickHangUp();
                break;
            case R.id.iv_mute: // 静音开关
                clickMute();
                break;
            case R.id.iv_handsfree: // 免提开关
                clickHangsFree();
                break;
            case R.id.root_layout:
                clickRoot();
                break;


        }
    }

    private void clickRoot() {
        if (callingState == CallingState.NORMAL) {
            if (bottomContainer.getVisibility() == View.VISIBLE) {
                bottomContainer.setVisibility(View.GONE);
                topContainer.setVisibility(View.GONE);

            } else {
                bottomContainer.setVisibility(View.VISIBLE);
                topContainer.setVisibility(View.VISIBLE);

            }
        }

    }

    private void clickHangsFree() {
        if (isHandsfreeState) {
            // 关闭免提
            handsFreeImage.setImageResource(R.mipmap.dl_icon_speaker_normal);
            closeSpeakerOn();
            isHandsfreeState = false;
        } else {
            handsFreeImage.setImageResource(R.mipmap.dl_icon_speaker_on);
            openSpeakerOn();
            isHandsfreeState = true;
        }

    }

    private void clickMute() {
        if (isMuteState) {
            // 关闭静音
            muteImage.setImageResource(R.mipmap.dl_icon_mute_normal);
            audioManager.setMicrophoneMute(false);
            isMuteState = false;
        } else {
            // 打开静音
            muteImage.setImageResource(R.mipmap.dl_icon_mute_on);
            audioManager.setMicrophoneMute(true);
            isMuteState = true;
        }

    }

    private void clickHangUp() {
        hangupBtn.setEnabled(false);
        if (soundPool != null)
            soundPool.stop(streamID);
        chronometer.stop();
        endCallTriggerByMe = true;
        callStateTextView.setText("正在挂断");
        try {
            EMChatManager.getInstance().endCall();
        } catch (Exception e) {
            e.printStackTrace();
            saveCallRecord();
            finish();
        }

    }

    private void clickAnswer() {
        answerBtn.setEnabled(false);
        if (ringtone != null)
            ringtone.stop();
        if (isInComingCall) {
            try {
                callStateTextView.setText("正在接听...");
                EMChatManager.getInstance().answerCall();
                cameraHelper.setStartFlag(true);

                openSpeakerOn();
                handsFreeImage.setImageResource(R.mipmap.dl_icon_speaker_on);
                isAnswered = true;
                isHandsfreeState = true;
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                saveCallRecord();
                finish();
                return;
            }
        }
        comingBtnContainer.setVisibility(View.INVISIBLE);
        hangupBtn.setVisibility(View.VISIBLE);
        voiceContronlLayout.setVisibility(View.VISIBLE);
        localSurfaceView.setVisibility(View.VISIBLE);

    }

    private void clickRefuse() {
        refuseBtn.setEnabled(false);
        if (ringtone != null)
            ringtone.stop();
        try {
            EMChatManager.getInstance().rejectCall();
        } catch (Exception e1) {
            e1.printStackTrace();
            saveCallRecord();
            finish();
        }
        callingState = CallingState.REFUESD;

    }

    /**
     * 本地SurfaceHolder callback
     */
    class LocalCallback implements SurfaceHolder.Callback {

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            cameraHelper.startCapture();
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
        }
    }

    /**
     * 对方SurfaceHolder callback
     */
    class OppositeCallback implements SurfaceHolder.Callback {

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
            callHelper.setRenderFlag(true);
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            callHelper.onWindowResize(width, height, format);
            if (!cameraHelper.isStarted()) {
                if (!isInComingCall) {
                    try {
                        // 拨打视频通话
                        EMChatManager.getInstance().makeVideoCall(userName);
                        // 通知cameraHelper可以写入数据
                        cameraHelper.setStartFlag(true);
                    } catch (EMServiceNotReadyException e) {
                        Toast.makeText(VideoCallActivity.this, "尚未连接服务器", 1).show();
                    }
                }

            }
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {

        }
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (soundPool != null) {
            soundPool.release();
        }
        if (ringtone != null && ringtone.isPlaying()) {
            ringtone.stop();
        }
        audioManager.setMode(AudioManager.MODE_NORMAL);
        audioManager.setMicrophoneMute(false);
        if (callStateListener != null) {
            EMChatManager.getInstance().removeCallStateChangeListener(callStateListener);
        }
        try {
            callHelper.setSurfaceView(null);
            cameraHelper.stopCapture();
            oppositeSurface = null;
            cameraHelper = null;
        } catch (Exception e) {
        }

    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        EMChatManager.getInstance().endCall();
        callDruationText = chronometer.getText().toString();
        saveCallRecord();
        finish();

    }

    //播放响铃
    private int playMakeCallSounds() {
        try {
            //最大音量
            float audioMaxVolumn = audioManager.getStreamMaxVolume(AudioManager.STREAM_RING);
            //当前音量
            float audioCurrentVolumn = audioManager.getStreamVolume(AudioManager.STREAM_RING);

            audioManager.setMode(AudioManager.MODE_RINGTONE);
            audioManager.setSpeakerphoneOn(false);
            int id = soundPool.play(outgoing, 0.3f, 0.3f, 1, -1, 1);
            return id;
        } catch (Exception e) {
            return -1;
        }
    }

    //打开扬声器
    private void openSpeakerOn() {
        try {
            if (!audioManager.isSpeakerphoneOn()) {
                audioManager.setSpeakerphoneOn(true);
            }
            audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //关闭扬声器
    private void closeSpeakerOn() {
        try {
            if (audioManager != null) {
                if (audioManager.isSpeakerphoneOn()) {
                    audioManager.setSpeakerphoneOn(false);
                }
                audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //保存通话记录
    private void saveCallRecord() {
        EMMessage message = null;
        TextMessageBody textBody = null;
        if (!isInComingCall) {
            message = EMMessage.createSendMessage(EMMessage.Type.TXT);
            message.setReceipt(userName);
        } else {
            message = EMMessage.createReceiveMessage(EMMessage.Type.TXT);
            message.setFrom(userName);
        }
        switch (callingState) {
            case NORMAL:
                textBody = new TextMessageBody("通话时长" + callDruationText);
                break;
            case REFUESD:
                textBody = new TextMessageBody("已拒绝");
                break;
            case BEREFUESD:
                textBody = new TextMessageBody("对方已拒绝");
                break;
            case OFFLINE:
                textBody = new TextMessageBody("对方不在线");
                break;
            case BUSY:
                textBody = new TextMessageBody("对方正在通话中");
                break;
            case NORESPONSE:
                textBody = new TextMessageBody("对方未接听");
                break;
            case UNANSWERED:
                textBody = new TextMessageBody("未接听");
                break;
            default:
                textBody = new TextMessageBody("已取消");
                break;
        }
        message.setAttribute(Constant.MESSAGE_ATTR_IS_VIDEO_CALL, true);
        message.addBody(textBody);
        message.setMsgId(msgId);
        EMChatManager.getInstance().saveMessage(message, false);


    }


    enum CallingState {
        CANCED, NORMAL, REFUESD, BEREFUESD, UNANSWERED, OFFLINE, NORESPONSE, BUSY
    }
}
